﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Objects;
using System.Linq;
using VO.Business.Utils;
using VO.Entities;

namespace VO.Business.Controllers
{
    public static class TracksController
    {
        public static List<Track> GetTracks()
        {
            using (ModelVOContainer ctx = new ModelVOContainer())
            {
                List<Track> list = ctx.Tracks.OrderBy(t => t.CreatedDate).ToList();
                list.Reverse();
                return list;
            }
        }

        public static List<Track> GetUserTracks(int userId)
        {
            using (ModelVOContainer ctx = new ModelVOContainer())
            {
                List<Track> list = ctx.Tracks.Where(p => p.UserId == userId).OrderBy(t => t.CreatedDate).ToList();
                list.Reverse();
                return list;
            }
        }

        public static Track GetTrack(Guid id)
        {
            using (ModelVOContainer ctx = new ModelVOContainer())
            {
                return ctx.Tracks.SingleOrDefault(p => p.Id == id);
            }
        }

        public static bool SaveTrack(Track track, bool isnew)
        {
            using (ModelVOContainer ctx = new ModelVOContainer())
            {
                track.LastEditDate = DateTime.Now;
                track.TrackLength = GeoUtils.GetTrackLength(track);

                //TODO - validate track validity (like minimum distance 200m between control posts and maximum length for a specific track category)
                track.IsValid = true;

                try
                {
                    if(isnew)
                    {
                        ctx.Tracks.Attach(track);
                        track.CreatedDate = DateTime.Now;
                        track.Id = Guid.NewGuid();//TODO - assure it is unique into DB
                        ctx.ObjectStateManager.ChangeObjectState(track, EntityState.Added);
                        return ctx.SaveChanges() > 0;
                    }
                    else
                    {
                        bool isLocked = false;
                        using (ModelVOContainer ctx2 = new ModelVOContainer())
                        {
                            isLocked = ctx2.Tracks.SingleOrDefault(p => p.Id == track.Id).Locked;
                        }
                        if (!isLocked)
                        {
                            ctx.Tracks.Attach(track);
                            ctx.ObjectStateManager.ChangeObjectState(track, EntityState.Modified);

                            return ctx.SaveChanges() > 0;
                        }
                        else
                        {
                            //update is locked - there are some done tracks
                            return false;
                        }
                    }
                    
                }
                catch (OptimisticConcurrencyException exOpt)
                {
                    ctx.Refresh(RefreshMode.ClientWins, track);

                    return ctx.SaveChanges() > 0;
                }
                catch (Exception)
                {
                    throw;
                }
            }
        }

        public static bool DeleteTrack(Guid trackId)
        {
            using (ModelVOContainer ctx = new ModelVOContainer())
            {
                try
                {
                    Track trToDelete = ctx.Tracks.SingleOrDefault(p => p.Id == trackId);
                    ctx.Tracks.DeleteObject(trToDelete);
                    return ctx.SaveChanges() > 0;
                }
                catch(Exception)
                {
                    throw;
                }
            }

        }
    }
}
